/* sub_header.h */

#ifndef DODO_SUB_HEADER_H
#define DODO_SUB_HEADER_H

#include "defines.h"
#include <fstream>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace dodomet
{
namespace mm5
{

class Sub_Header;

class Sub_Header_Impl
{
public:
	friend class Sub_Header;
public:
	typedef fortran_int int_type;
	typedef fortran_real real_type;
private:
	Sub_Header_Impl();
	Sub_Header_Impl(const Sub_Header_Impl& orig);
	
	// read from file
	void read(std::fstream& stream);
	// operation
	void set_start_time(boost::posix_time::ptime start_time);
	// queries
	int ndim() const;
	int start_index(int dim) const;
	int end_index(int dim) const;
	std::string name() const;
	std::string unit() const;
	std::string description() const;
	boost::posix_time::ptime start_time() const;
	boost::posix_time::time_duration xtime() const;
	real_type xtime_real() const;

	int staggering() const;
	int ordering() const;
	
	std::streampos field_pos() const;
private:
	int_type ndim_;
	int_type start_index_[4];
	int_type end_index_[4];
	real_type xtime_;
	int staggering_;
	int ordering_;
	char current_date_[24 + 1];
	char name_[9 + 1];
	char unit_[25 + 1];
	char description_[46 + 1];
	int use_count_;

	std::streampos field_pos_;
	boost::posix_time::ptime start_time_;
};

class Sub_Header
{
public:
	typedef Sub_Header_Impl::int_type int_type;
	typedef Sub_Header_Impl::real_type real_type;
public:
	// reading from file
	void read(std::fstream& stream);
	// operation
	void set_start_time(boost::posix_time::ptime start_time);
	// queries
	int ndim() const;
	int start_index(int dim) const;
	int end_index(int dim) const;
	std::string name() const;
	std::string unit() const;
	std::string description() const;
	boost::posix_time::ptime start_time() const;
	boost::posix_time::time_duration xtime() const;
	real_type xtime_real() const;

	int staggering() const;
	int ordering() const;

	std::streampos field_pos() const;
public:
	Sub_Header();
	Sub_Header(const Sub_Header& orig);
	~Sub_Header();

	Sub_Header& operator= (const Sub_Header& orig);
	void on_write();
private:
	Sub_Header_Impl* impl_;
	
};


} // namespace mm5
} // namespace dodomet

#endif //DODO_SUB_HEADER_H

